<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:doc="livcos.org/ns/doc"
  xmlns="http://www.w3.org/1999/xhtml"
  xmlns:v="livcos.org/ns/view"
  exclude-result-prefixes="doc v">

	<xsl:template match="doc:markup">
    <p id="{@id}">
    	<v:style ref="{resolve-uri('styles.css')}"/>
    	<xsl:apply-templates select="node()" mode="markup"/>
    </p>
  </xsl:template>
  
  <!-- basic elements -->
  <xsl:template match="*" mode="markup">
    <xsl:variable name="first" select="not(preceding-sibling::*) and (name(..) = 'markup')"/>
		<xsl:if test="not($first)">
			<br/>
		</xsl:if>
    <xsl:call-template name="markup.indent"/>
    <span class="markup_element">
      <xsl:text><![CDATA[<]]></xsl:text>
      <xsl:value-of select="name(.)"/>
      <xsl:apply-templates select="@*" mode="markup"/>
      <xsl:call-template name="namespace_markup"/>
      <xsl:text><![CDATA[>]]></xsl:text>
    </span>
    <xsl:apply-templates select="node()" mode="markup"/>
    <br/>
  	<xsl:call-template name="markup.indent"/>
    <span class="markup_element">
      <xsl:text><![CDATA[<]]>/</xsl:text>
      <xsl:value-of select="name(.)"/>
      <xsl:text><![CDATA[>]]></xsl:text>
    </span>
  </xsl:template>
  
  <!-- elements with direct text children -->
	<xsl:template match="*[text()[normalize-space(.) != '']]" mode="markup">
    <xsl:variable name="first" select="not(preceding-sibling::*) and (name(..) = 'markup')"/>
  		<xsl:if test="../text()[normalize-space(.) = '']">
			<xsl:if test="not($first)">
				<br/>
			</xsl:if>
      <xsl:call-template name="markup.indent"/>
    </xsl:if>
    <span class="markup_element">
      <xsl:text><![CDATA[<]]></xsl:text>
      <xsl:value-of select="name(.)"/>
      <xsl:apply-templates select="@*" mode="markup"/>
      <xsl:call-template name="namespace_markup"/>
      <xsl:text><![CDATA[>]]></xsl:text>
    </span>
    <xsl:apply-templates select="node()" mode="markup"/>
    <span class="markup_element">
      <xsl:text><![CDATA[<]]>/</xsl:text>
      <xsl:value-of select="name(.)"/>
      <xsl:text><![CDATA[>]]></xsl:text>
    </span>
  </xsl:template>
  
  <!-- empty elements -->
  <xsl:template match="*[count(node()) &lt; 1]" mode="markup">
    <xsl:variable name="first" select="not(preceding-sibling::*) and (name(..) = 'markup')"/>
  	<xsl:if test="../text()[normalize-space(.) = '']">
			<xsl:if test="not($first)">
				<br/>
			</xsl:if>
      <xsl:call-template name="markup.indent"/>
    </xsl:if>
    <span class="markup_element">
      <xsl:text><![CDATA[<]]></xsl:text>
      <xsl:value-of select="name(.)"/>
      <xsl:apply-templates select="@*" mode="markup"/>
      <xsl:call-template name="namespace_markup"/>
      <xsl:text>/<![CDATA[>]]></xsl:text>
    </span>
  </xsl:template>
  
  <!-- attributes -->
  <xsl:template match="@*" mode="markup">
    <xsl:text> </xsl:text>
    <span class="markup_attribute">
      <xsl:value-of select="name(.)"/>
      <xsl:text>=</xsl:text>
      <span class="markup_attribute_value">
        <xsl:text>"</xsl:text>
        <xsl:value-of select="."/>
        <xsl:text>"</xsl:text>
      </span>
    </span>
  </xsl:template>
  
  <!-- namespaces -->
  <xsl:template name="namespace_markup">
    <xsl:variable name="e" select="." />
    <xsl:for-each select="namespace::*[name(.) != 'xml']">
      <xsl:variable name="n" select="name(.)" />
      <xsl:if test="not($e/ancestor::*[namespace::*[name(.) = $n]])">
        <xsl:text> </xsl:text>
        <span class="markup_attribute">
          <xsl:text>xmlns:</xsl:text>
          <xsl:value-of select="name(.)"/>
          <xsl:text>=</xsl:text>
          <span class="markup_attribute_value">
            <xsl:text>"</xsl:text>
            <xsl:value-of select="."/>
            <xsl:text>"</xsl:text>
          </span>
        </span>
      </xsl:if>
    </xsl:for-each>
  </xsl:template>
  
  <!-- comments -->
  <xsl:template match="comment()" mode="markup">
    <span class="markup_comment">
      <xsl:text><![CDATA[<]]>!--</xsl:text>
      <xsl:value-of select="."/>
      <xsl:text>--<![CDATA[>]]></xsl:text>
    </span>
  </xsl:template>

  <!-- text -->
  <xsl:template match="text()" mode="markup">
    <xsl:value-of select="."/>
  </xsl:template>
  
  <!-- text -->
  <xsl:template match="text()[matches(.,'\s*\n\s*\n\s*')]" mode="markup">
    <br/>
  </xsl:template>
  
  <!-- processing instructions -->
  <xsl:template match="processing-instruction()" mode="markup">
    <xsl:text><![CDATA[<]]>?xml</xsl:text>
    <xsl:value-of select="."/>
    <xsl:text>?<![CDATA[>]]></xsl:text>
  </xsl:template>
  
  <xsl:template name="markup.indent">
    <xsl:variable name="offset" select="count(ancestor::doc:markup[last()]/ancestor::*)"/>
    <xsl:for-each select="ancestor::*">
      <xsl:if test="position() &gt; $offset"><xsl:text>&#160;&#160;</xsl:text></xsl:if>
    </xsl:for-each>
  </xsl:template>

</xsl:stylesheet>
